package com.miplus.ccrm.core.service.strategy;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.EnumRCode;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.common.ServiceException;
import com.miplus.ccrm.core.controller.vo.LabelResVo;
import com.miplus.ccrm.core.controller.vo.strategy.CpListEditVo;
import com.miplus.ccrm.core.controller.vo.strategy.CpListReqVo;
import com.miplus.ccrm.core.controller.vo.strategy.CpListResVo;
import com.miplus.ccrm.core.controller.vo.strategy.StrategyEditVo;
import com.miplus.ccrm.core.mapper.FiTaskMapper;
import com.miplus.ccrm.core.pojo.CpCalllist;
import com.miplus.ccrm.core.mapper.CpCalllistMapper;
import com.miplus.ccrm.core.pojo.CpStrategy;
import com.miplus.ccrm.core.pojo.FiTask;
import com.miplus.ccrm.core.service.aiqm.QmTemplateService;
import com.miplus.ccrm.core.service.conf.MsgDefineService;
import com.miplus.ccrm.core.utils.EnumFiChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author pc
* @description 针对表【cp_calllist的数据库操作Service实现
* @createDate 2024-03-21 16:08:15
*/
@Slf4j
@Service
public class CpCalllistServiceImpl extends MPJBaseServiceImpl<CpCalllistMapper, CpCalllist>
    implements CpCalllistService{
    @Resource
    private MsgDefineService defineService;
    @Resource
    private QmTemplateService qmTemplateService;
    @Resource
    private CpScriptTempService scriptTempService;
    @Resource
    private FiTaskMapper fiTaskMapper;
    @Resource
    private CpStrategyService cpStrategyService;

    @Override
    public IPage<CpListResVo> campaignList(CpListReqVo paras)
    {
        return selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                CpListResVo.class,
                new MPJLambdaWrapper<CpCalllist>()
                        .selectAs("dbo.fun_getnames('CAMPAIGN.SCREENTYPE',t.apptype)",CpListResVo::getAppname)
                        .selectAs("dbo.fun_getnames('CAMPAIGN.CHANNEL',t.channel)",CpListResVo::getChannelname)
                        .selectAs("(select tg.name from CP_CALLLIST_TRIGGER tg where CONVERT(varchar, tg.triggerid) = t.triggerid)",CpListResVo::getTriggername)
                        .selectAll(CpCalllist.class)
                        .eq(paras.getState()!=null,"state",paras.getState())
                        .like(JPubUtils.IsNotEmpty(paras.getName()),"name",paras.getName())
                        .orderByAsc("clid")
        );
    }

    @Override
    public CmdResVo campaignUpdate(String $usrid, CpListEditVo paras)
    {
        CpCalllist def=new CpCalllist();
        BeanUtils.copyProperties(paras,def);
        if(JPubUtils.IsEmpty(paras.getWfid())){
            def.setWfid(null);
        }
        if (JPubUtils.IsEmpty(paras.getTriggerid())) {
            def.setTriggerid(null);
        }
        def.setMddt(new Date());
        def.setMdusr($usrid);
        int ret=baseMapper.updateById(def);
        return new CmdResVo(ret,def.getClid());
    }

    @Override
    public CmdResVo campaignInsert(String $usrid,CpListEditVo paras)
    {
        CpCalllist def=new CpCalllist();
        BeanUtils.copyProperties(paras,def);
        def.setCrdt(new Date());
        def.setCrusr($usrid);
        def.setMddt(new Date());
        def.setMdusr($usrid);
        int ret=baseMapper.insert(def);
        if(def.getChannel()==2){
            // 1. 查询原始策略（保留旧数据）
            List<CpStrategy> sct=cpStrategyService.list(new QueryWrapper<CpStrategy>().eq("clid","AI_DIAL"));
            // 2. 创建新副本并重置主键
            List<CpStrategy> newStrategies = sct.stream().map(origin -> {
                CpStrategy copy = new CpStrategy();
                BeanUtils.copyProperties(origin, copy);  // 复制属性
                copy.setStrategyid(null);                // 清空主键（触发序列生成）
                copy.setClid(def.getClid());             // 设置新clid
                return copy;
            }).collect(Collectors.toList());
            // 3. 单条插入替代批量插入(sql-server 不支持mp的批量插入,需自定义)
            for (CpStrategy strategy : newStrategies) {
                cpStrategyService.save(strategy);
            }
        }
        return new CmdResVo(ret,def.getClid());
    }

    @Override
    public CmdResVo campaignDelete(String id)
    {
        int ret=baseMapper.deleteById(id);
        return new CmdResVo(ret,id);
    }

    @Override
    public List<LabelResVo> campaignSelectList(Integer status,Integer channel)
    {
        return baseMapper.campaignSelectList(status,channel);
    }

    @Override
    public Integer getCalllistWfID(String clid)
    {
        CpCalllist def=baseMapper.selectById(clid);
        if(def==null) return 0;
        Integer ret=def.getWfid();
        //可能没有设置工作流
        if(ret==null) ret=0;
        return ret;
    }

    @Override
    public String getClid(Integer channel)
    {//.last("limit 1")
        CpCalllist def=baseMapper.selectOne(new QueryWrapper<CpCalllist>()
                .eq("channel",channel)
                .eq("rownum",1)
        );
        if(def==null) return "";
        return def.getClid();
    }

    @Override
    public List<LabelResVo> dialSelectList(Integer status)
    {
        return baseMapper.dialSelectList(status);
    }

    @Override
    public List<LabelResVo> qmSelectList(Integer status)
    {
        return baseMapper.qmSelectList(status);
    }

    @Override
    public List<LabelResVo> getTemplateList(Integer channel)
    {
        if(channel==1) {
            return defineService.getMsgTmpList();
        }
        else if(channel==2){
            return scriptTempService.getTempList();
        }
        else if(channel==20){
            return qmTemplateService.getTempList();
        }
        return new ArrayList<>();
    }

    @Override
    public boolean checkActionOk(Integer ficaseid, String clid, EnumFiChannel enumFiChannel)
    {
        CpCalllist calllist=baseMapper.selectById(clid);
        if(calllist==null) return true;

        Integer state=calllist.getState();
        if(!JPubUtils.IsEqual(state,1)){
            throw new ServiceException(EnumRCode.ClDisable.value, EnumRCode.ClDisable.name);
        }

        String starttime=calllist.getStarttime();
        String endtime=calllist.getEndtime();
        if(JPubUtils.IsNotEmpty(starttime)&&JPubUtils.IsNotEmpty(endtime)){
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            String currtime=sdf.format(new Date());
            if(currtime.compareTo(starttime)<0||currtime.compareTo(endtime)>0){
                log.warn("checkActionOk({}):{}.ValidTime:{}~{}",clid,enumFiChannel.name,starttime,endtime);
                throw new ServiceException(EnumRCode.ClValidTime.value, EnumRCode.ClValidTime.name);
            }
        }

        Integer maxcnt=calllist.getDialcnt();
        if(maxcnt!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Long cnt=fiTaskMapper.selectCount(
                    new MPJLambdaWrapper<FiTask>()
                            .eq(FiTask::getOriginnumber,ficaseid)
                            .eq(FiTask::getChannel,enumFiChannel.value)
                            .ge(FiTask::getCrdt,JPubUtils.StringToDate(sdf.format(new Date())))
                            .select(FiTask::getTasknumber)
            );
            if(cnt>=maxcnt){
                log.warn("checkAction({}):{}.Cnt={},MaxCnt={}",ficaseid,enumFiChannel.name,cnt,maxcnt);
                throw new ServiceException(EnumRCode.ClMaxCount.value, EnumRCode.ClMaxCount.name);
            }
        }
        return true;
    }
}




